package thread;
/**
 * 如何让两个线程按照指定方式有序交叉运行呢？
 */
public class Main {
    int i = 1;   //i和istrue作为多线程的共享数据
    boolean istrue = false;

    public static void main(String[] args) {
        Main main = new Main();
        ThreadA a = new ThreadA(main);
        ThreadB b = new ThreadB(main);
        Thread threada = new Thread(a);
        Thread threadb = new Thread(b);
        threada.start();
        threadb.start();

    }}

class ThreadA implements Runnable {
    Main main;

    public ThreadA(Main main) {
        this.main = main;
    }

    public void run() {
        while (main.i <= 10) {
            synchronized (main) { // 必须要用一把锁对象，这个对象是main
                if (!main.istrue) {
                    try {
                        main.wait(); // 操作wait()函数的必须和锁是同一个
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.println("奇数：" + main.i);
                    main.i++;
                    main.istrue = false;
                    main.notifyAll();
                }
            }}}}

class ThreadB implements Runnable {
    Main main;

    public ThreadB(Main main) {
        this.main = main;
    }

    public void run() {
        while (main.i <= 10) {
            synchronized (main) { // 必须要用一把锁对象，这个对象是main
                if (main.istrue) {
                    try {
                        main.wait(); // 操作wait()函数的必须和锁是同一个
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.println("偶数：" + main.i);
                    main.i++;
                    main.istrue = true;
                    main.notifyAll();
                }
            }}}}

//梳理下流程
//首先传入一个 A 和 B 共享的对象锁main;
//当 A 得到锁后，直接交出锁的控制权，进入 wait 状态；
//对 B 而言，由于 A 最开始得到了锁，导致 B 无法执行；直到 A 调用wait() 释放控制权后， B 才得到了锁，同时输出：偶数：1，同时notifyAll让A又到就绪状态
//接下来A和B都有可能获得cpu时间碎片，当 A 得到锁后，那么打印奇数：2，如果B又获得cpu时间片，那么它会进入wait状态。
//就这样来去循环，最终就是交叉打印运行。
